#include <coroutine>
#include <iostream>

struct MyCoroutine {
  struct promise_type {
    int value = 0;
    bool has_value = false;

    MyCoroutine get_return_object() {
      std::cout << "  [Promise] get_return_object() 被调用" << std::endl;
      return MyCoroutine{std::coroutine_handle<promise_type>::from_promise(*this)};
    }
    
    std::suspend_never initial_suspend() {
      std::cout << "  [Promise] initial_suspend() 被调用，返回suspend_never(不暂停)" << std::endl;
      return {};
    }
    
    std::suspend_always final_suspend() noexcept {
      std::cout << "  [Promise] final_suspend() 被调用，返回suspend_always(暂停)" << std::endl;
      return {};
    }
    
    void return_void() {
      std::cout << "  [Promise] return_void() 被调用" << std::endl;
    }
    
    void unhandled_exception() {
      std::cout << "  [Promise] unhandled_exception() 被调用" << std::endl;
    }

    std::suspend_always yield_value(int val) {
      std::cout << "  [Promise] yield_value(" << val << ") 被调用 - 开始处理" << std::endl;
      this->value = val;
      this->has_value = true;
      std::cout << "  [Promise] 值已保存到promise.value = " << val << std::endl;
      std::cout << "  [Promise] yield_value() 返回suspend_always，协程即将暂停" << std::endl;
      return {};  // 返回suspend_always，导致协程暂停
    }
  };

  std::coroutine_handle<promise_type> h;

  MyCoroutine(std::coroutine_handle<promise_type> h) : h(h) {
    std::cout << "  [Coroutine] MyCoroutine构造函数被调用" << std::endl;
  }

  // 移动构造函数和移动赋值运算符
  MyCoroutine(MyCoroutine&& other) noexcept : h(other.h) {
    other.h = {};
    std::cout << "  [Coroutine] 移动构造函数被调用" << std::endl;
  }
  
  MyCoroutine& operator=(MyCoroutine&& other) noexcept {
    if (this != &other) {
      if (h) h.destroy();
      h = other.h;
      other.h = {};
    }
    return *this;
  }

  // 禁用拷贝
  MyCoroutine(const MyCoroutine&) = delete;
  MyCoroutine& operator=(const MyCoroutine&) = delete;

  ~MyCoroutine() {
    std::cout << "  [Coroutine] 析构函数被调用" << std::endl;
    if (h) h.destroy();
  }

  // 安全的resume方法
  bool resume() {
    if (h && !h.done()) {
      std::cout << "  [主函数] 准备调用resume()..." << std::endl;
      h.resume();
      std::cout << "  [主函数] resume()调用完成，协程已暂停或结束" << std::endl;
      return !h.done();
    }
    return false;
  }

  // 检查协程是否完成
  bool done() const {
    return !h || h.done();
  }

  // 获取当前值
  int current_value() const {
    if (h && h.promise().has_value) {
      return h.promise().value;
    }
    return 0;
  }
  
  // 检查是否有值可用
  bool has_value() const {
    return h && h.promise().has_value;
  }
};

struct MyAwaiter {
  std::future<int> future;

  bool await_ready() {
    return future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
  }

  void await_suspend(std::coroutine_handle<> handle) {
    std::cout << "  [Awaiter] await_suspend() 被调用" << std::endl;
    std::thread([this]() {
      future.get();
      std::cout << "  [Awaiter] 协程被唤醒" << std::endl;
      handle.resume();
    }).detach();
  }

  int await_resume() {
    std::cout << "  [Awaiter] await_resume() 被调用" << std::endl;
    return future.get();
  }
};


MyCoroutine my_coroutine() {
  std::cout << "[协程函数] 开始执行 my_coroutine()" << std::endl;
  
  std::cout << "[协程函数] 即将执行 co_yield 3" << std::endl;
  co_yield 3;  // 这里发生了什么？
  
  std::cout << "[协程函数] 从第一次yield继续执行" << std::endl;
  
  std::cout << "[协程函数] 即将执行 co_yield 2" << std::endl;
  co_yield 2;  // 这里又发生了什么？
  
  std::cout << "[协程函数] 从第二次yield继续执行，即将结束" << std::endl;
  // 函数结束会自动调用return_void()和final_suspend()
}

int main(int argc, char *argv[]) {
  std::cout << "=== 开始创建协程 ===" << std::endl;
  MyCoroutine coro = my_coroutine();
  
  std::cout << "\n=== 协程创建完成，分析当前状态 ===" << std::endl;
  std::cout << "协程是否完成: " << (coro.done() ? "是" : "否") << std::endl;
  if (coro.has_value()) {
    std::cout << "当前值: " << coro.current_value() << std::endl;
  }
  
  std::cout << "\n=== 第一次调用resume ===" << std::endl;
  if (coro.resume()) {
    std::cout << "协程状态 - 完成: " << (coro.done() ? "是" : "否") << std::endl;
    if (coro.has_value()) {
      std::cout << "当前值: " << coro.current_value() << std::endl;
    }
  }
  
  std::cout << "\n=== 第二次调用resume ===" << std::endl;
  if (coro.resume()) {
    std::cout << "协程状态 - 完成: " << (coro.done() ? "是" : "否") << std::endl;
  }
  
  std::cout << "\n=== 尝试第三次resume ===" << std::endl;
  if (!coro.resume()) {
    std::cout << "协程已经完成，无法再次resume" << std::endl;
  }
  
  std::cout << "\n=== 程序结束，协程对象即将销毁 ===" << std::endl;
  
  return 0;
}
